package org.tokaf.rater;

import org.tokaf.TopKElement;
import org.tokaf.datasearcher.DataSearcher;

/**
 * <p>Base class for all raters. It represents aggregating function and should
 * obey its limitations.</p> <p>Copyright (c) 2006</p>
 * @author Alan Eckhardt
 * @version 1.0
 */
public abstract class Rater {

	// Names of predicates, which connects object to its ratings.
	String fields[];

	/**
	 * Rates element el. It returns the rating and stores the rating in
	 * TopKElement.
	 * @param el Element to be rated.
	 * @param data DataSearchers, that can be used to compute the rating.
	 * @return double the rating of object.
	 */
	public double rate(TopKElement el, DataSearcher data[]) {
		double res = getRating(el, data);
		el.rating = res;
		return res;
	}

	/**
	 * Return the rating, where all missing attributes are replaced with zero.
	 * @param el Element to be rated.
	 * @param data DataSearchers, that can be used to compute the rating.
	 * @return double the rating of object.
	 */
	public double getRating(TopKElement el, DataSearcher data[]) {
		return getRating(el, data, 0);
	}

	/**
	 * Return the rating, where all missing attributes are replaced with
	 * optional value.
	 * @param el Element to be rated.
	 * @param data DataSearchers, that can be used to compute the rating.
	 * @param optional double value, that replaces missing attributes.
	 * @return double the rating of object.
	 */
	public abstract double getRating(TopKElement el, DataSearcher data[],
			double optional);

	/**
	 * Return the rating, where all missing attributes are replaced with the
	 * rating of that attribute of element optional.
	 * @param el Element to be rated.
	 * @param data DataSearchers, that can be used to compute the rating.
	 * @param optional TopKElement is the element, whose rating of attributes
	 *            are used instead of missing values.
	 * @return double the rating of object.
	 */
	public abstract double getRating(TopKElement el, DataSearcher data[],
			TopKElement optional);

	/**
	 * Compares two TopKElements, using their ratings.
	 * @param el1 First TopKElement
	 * @param el2 Second TopKElement
	 * @param data DataSearchers, that can be used to compute the rating.
	 * @return 1, when el1 is greater than el2, -1, when el2 is greater than
	 *         el1, 0 if they are equal
	 */
	public int compare(TopKElement el1, TopKElement el2, DataSearcher data[]) {
		double res1 = rate(el1, data);
		double res2 = rate(el2, data);
		if (res1 > res2)
			return 1;
		if (res1 < res2)
			return -1;
		return 0;
	}

	/**
	 * Returns the partial derivation of rater in point el.
	 * @param index The index, in which the partial derivation is computed.
	 * @param data DataSearchers, that can be used to compute the rating.
	 * @param el Element in which the derivation is computed.
	 * @return double the values of partial derivation.
	 */
	public abstract double getDerivation(int index, DataSearcher data[],
			TopKElement el);

}
